package com.atguigu.tingshu.payment.service.impl;

import com.atguigu.tingshu.account.client.RechargeInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.account.RechargeInfo;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.order.client.OrderInfoFeignClient;
import com.atguigu.tingshu.payment.config.WxPayV3Config;
import com.atguigu.tingshu.payment.service.PaymentInfoService;
import com.atguigu.tingshu.payment.service.WxPayService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
@SuppressWarnings({"all"})
public class WxPayServiceImpl implements WxPayService {

	@Autowired
	private PaymentInfoService paymentInfoService;
	@Autowired
	private WxPayV3Config wxPayV3Config;
	@Autowired
	private UserInfoFeignClient userInfoFeignClient;
	@Autowired
	private OrderInfoFeignClient orderInfoFeignClient;
	@Autowired
	private RechargeInfoFeignClient rechargeInfoFeignClient;
	@Override
	public Map<String, Object> createJsapi(String paymentType, String orderNo, Long userId) {
		//初始化支付总金额
		BigDecimal totalAmount = new BigDecimal("0.00");
		String content = "";
		//记录支付表
		if (paymentType.equals(SystemConstant.PAYMENT_TYPE_ORDER)){
			//订单
			Result<OrderInfo> orderInfoResult = orderInfoFeignClient.getOrderInfo(orderNo);
			Assert.notNull(orderInfoResult, "订单不存在");
			OrderInfo orderInfo = orderInfoResult.getData();
			Assert.notNull(orderInfo, "订单不存在");
			if (!orderInfo.getOrderStatus().equals(SystemConstant.ORDER_STATUS_UNPAID)){
				//订单已付款或已取消，无需继续付款
				throw new GuiguException(ResultCodeEnum.REPEAT_BUY_ERROR);
			}
			totalAmount = orderInfo.getOrderAmount();
			content = "支付订单";
		}else {
			//充值
			Result<RechargeInfo> rechargeInfoResult = rechargeInfoFeignClient.getRechargeInfo(orderNo);
			Assert.notNull(rechargeInfoResult, "充值订单不存在");
			RechargeInfo rechargeInfo = rechargeInfoResult.getData();
			Assert.notNull(rechargeInfo, "充值订单不存在");
			if (!rechargeInfo.getRechargeStatus().equals(SystemConstant.ORDER_STATUS_UNPAID)){
				//订单已付款或已取消，无需继续付款
				throw new GuiguException(ResultCodeEnum.REPEAT_BUY_ERROR);
			}
			totalAmount = rechargeInfo.getRechargeAmount();
			content = "充值业务，金额:"+totalAmount;
		}
		//保存支付交易信息记录
		paymentInfoService.savePaymentInfo(orderNo,userId, paymentType, totalAmount,SystemConstant.ORDER_PAY_WAY_WEIXIN,content);
		//调用微信支付
		RSAAutoCertificateConfig config = wxPayV3Config.getConfig();
		JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
		PrepayRequest request = new PrepayRequest();
		Amount amount = new Amount();
		amount.setTotal(1);
		request.setAmount(amount);
		request.setAppid(wxPayV3Config.getAppid());
		request.setMchid(wxPayV3Config.getMerchantId());
		request.setDescription("测试商品标题");
		request.setNotifyUrl(wxPayV3Config.getNotifyUrl());
		request.setOutTradeNo(orderNo);
		Payer payer = new Payer();
		//远程调用获取用户openid
		Result<UserInfo> userInfoResult = userInfoFeignClient.getUserInfo(userId);
		Assert.notNull(userInfoResult, "用户远程调用失败");
		UserInfo userInfo = userInfoResult.getData();
		Assert.notNull(userInfo, "用户为空");
		payer.setOpenid(userInfo.getWxOpenId());
		request.setPayer(payer);
		// response包含了调起支付所需的所有参数，可直接用于前端调起支付
		PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
		Map<String, Object> result = new HashMap<>();
		result.put("timeStamp", response.getTimeStamp()); // 时间戳
		result.put("nonceStr", response.getNonceStr());   // 随机字符串
		result.put("package", response.getPackageVal());  // 订单详情扩展字符串
		result.put("signType", response.getSignType());   // 签名方式
		result.put("paySign", response.getPaySign());     // 签名
		return result;
	}
}
